﻿<!DOCTYPE html>
<html>
<head>
  <title>ol-ext: Simplify a source</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <meta name="description" content="Calculate the convex hull of a set of points." />
  <meta name="keywords" content="ol3, geom, polygon, simplify" />

  <!-- jQuery -->
  <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>

  <!-- Openlayers -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>

  
  <!-- ol-ext -->
  <link rel="stylesheet" href="../../dist/ol-ext.css" />
  <script type="text/javascript" src="../../dist/ol-ext.js"></script>
  <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
  <script src="https://unpkg.com/elm-pep"></script>
  <!-- filesaver-js -->
  <script type="text/javascript" src="https://cdn.rawgit.com/eligrey/FileSaver.js/aa9f4e0e/FileSaver.min.js"></script>

  <link rel="stylesheet" href="../style.css" />
  <style>
    #map {
      margin: 0;
      width: 100%;
      min-height: 60vh;
      height: 20em;
    }
    .options {
      position: fixed;
      right: 0;
      text-align: right;
    }
    input[type="range"] {
      display: block;
      width: 20em;
    }
    #simplificator {
      display: none;
      margin-top: .5em;
    }
    .ol-ext-toggle-switch,
    .ol-input-range {
      display: block;
    }
    .ol-input-range input {
      float: right;
    }
    #simplificator button {
      min-width: 10em;
      margin-top: .5em;
    }
  </style>
</head>
<body >
  <a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

  <a href="../../index.html">
    <h1>ol-ext: Simplify a Vector source</h1>
  </a>
  <div class="info">
  </div>

  <!-- Map div -->
  <div id="map"></div>
  
  <div class="options">
    <button onclick="simplify()">Simplify</button>
    <div id="simplificator">
      <input type="number" min="0" max="99" value="0" />
      <input class="visva" type="checkbox" />
      <span class="nb"></span> points
      <br/>
      <button onclick="simplificator.getFeatures(); $('.save').prop('disabled', false)">Apply</button>
      <button class="save" onclick="save()" disabled>Save</button>
    </div>
  </div>

  <script type="text/javascript">

  // Two base layers
  var layer = new ol.layer.Geoportail({ layer: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2', visible: false })

  // The map
  var map = new ol.Map({
    target: 'map',
    view: new ol.View({
      zoom: 7,
      center: [205461, 5867916]
    }),
    layers: [layer]
  });

  var vectorSource = new ol.source.Vector({
    url: '../data/departements.geojsonx',
    format: new ol.format.GeoJSONX(),
    attributions: [ "&copy; <a href='https://www.insee.fr'>INSEE</a>", "&copy; <a href='https://www.data.gouv.fr/fr/datasets/geofla-r/'>IGN</a>" ],
  });
  map.addLayer(new ol.layer.VectorImage({
    name: 'Departements',
    source: vectorSource,
  }))

  var ddrop = new ol.interaction.DropFile()
  map.addInteraction(ddrop)
  ddrop.on('addfeatures', function(e) {
    console.log('loading')
    vectorSource.clear();
    vectorSource.addFeatures(e.features);
    map.getView().fit(vectorSource.getExtent());
    simplify();
  })

/*
  var result = new ol.source.Vector
  map.addLayer(new ol.layer.Vector({
    name: 'Simplify',
    source: result,
    style: new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'red',
        with: 1.5
      })
    })
  }))
*/

  var layer = new ol.layer.VectorImage({
    source: new ol.source.Vector,
    style: function(f) {
      return new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: f.get('edge').length > 1 ? 'red' : 'green',
          with: 1.5
        })
      })
    }
  })
  map.addLayer(layer)

  var sel = new ol.interaction.Select({
    // layers: [layer],
    hitTolerance: 3,
    multi: true
  })
  map.addInteraction(sel)
  sel.on('select', function(e) {
    var f = e.selected[0];
    if (f) {
      console.log(e.selected, f.getProperties())
    }
  })

  var simplificator, nb0;
  function simplify() {
    simplificator = new ol.geom.Simplificator()
    simplificator.setFeatures(vectorSource.getFeatures(), 3);
    layer.getSource().clear();
    layer.getSource().addFeatures(simplificator.getEdges());
    // Count vertex
    nb0 = 0;
    simplificator.getEdges().forEach(function(f) {
      nb0 += f.getGeometry().getCoordinates().length
    });
    document.querySelector('.nb').innerHTML = nb0.toLocaleString();
    document.getElementById('simplificator').style.display = 'block';
    document.querySelector('.options button').style.display = 'none';
  }

  var range = new ol.ext.input.Range({ 
    input: document.querySelector('#simplificator input')
  });
  range.on('change:value', function(e) { 
    if (!filtering) {
      filter(e.value)
    }
  })

  var check = new ol.ext.input.Switch({
    input: document.querySelector('#simplificator input[type="checkbox"]'),
    html: 'Douglas Peucker', 
    after: 'Visvalingam'
  })
  check.on('check', function() { filter(range.getValue()) });

  var filtering = false;
  function filter(val) {
    val = parseFloat(val)
    if (simplificator) {
      filtering = true;
      if (check.isChecked()) {
        var ex = vectorSource.getFeatures()[0].getGeometry().getExtent()
        var d = ol.coordinate.dist2d([ex[0], ex[1]], [ex[2], ex[3]]) / 50000;
        simplificator.simplifyVisvalingam({
          dist: (d * val*val) || .1,
          minPoints: 4
        })
      } else {
        var ex = vectorSource.getFeatures()[0].getGeometry().getExtent()
        var d = ol.coordinate.dist2d([ex[0], ex[1]], [ex[2], ex[3]]) / 500000;
        simplificator.simplify(d * val*val)
      }
      var nb = 0;
      simplificator.getEdges().forEach(function(f) {
        nb += f.getGeometry().getCoordinates().length
      });
      document.querySelector('.nb').innerHTML = nb.toLocaleString() + '/' + nb0.toLocaleString();
      setTimeout(function() { 
        filtering = false;
        if (range.getValue() != val) filter(range.getValue())
      }, 0);
    }
  }

  function save() {
    var features = vectorSource.getFeatures();
    var format = new ol.format.GeoJSON();
    var data = format.writeFeatures(features, { dataProjection: 'EPSG:4326', featureProjection: map.getView().getProjection()});
    var blob = new Blob([data], {type: "text/plain;charset=utf-8"});
    saveAs(blob, "map.geojson");
  }

  </script>
  
</body>
</html>